<template>
  <div :class="{ 'canvas-wrap': isLandscape, 'canvas-wrap-stand': !isLandscape }">
    <div class="canvas-box">
      <canvas id="canvas" />
    </div>
    <div class="canvas-btns">
      <div class="canvas-btns-content">
        <div><el-button type="primary" class="btn" @click="complete">完成</el-button></div>
        <div><el-button class="btn" @click="clear">清空</el-button></div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import FileAPI from "@/api/file.api";
import SmoothSignature from "smooth-signature";
import { onMounted } from "vue";
import { decryptDES } from "@/utils/des";
import ContractAPI from "@/api/flow/contract.api";
import ContractDesignAPI from "@/api/flow/contractDesign.api";
import { Auth } from "@/utils/auth";
import { debounce } from "lodash-es";

const route = useRoute();
const isLandscape = ref(false); //是否已经横屏
let signature: SmoothSignature;

const debounceLandscape = debounce(forceLandscape, 200); //防抖

/**
 * 业务信息
 * @param id 业务id
 * @param type 业务类型 customerSign-合同签订 designSign-设计确认
 * @param token 令牌
 */
const contractInfo = ref<{
  type: string;
  id: string;
  token: string;
}>();

watch(
  () => route.query.key,
  (val) => {
    const str = decryptDES(val as string);
    contractInfo.value = JSON.parse(str) || {}; //业务信息
    // 设置token
    Auth.setToken(contractInfo.value?.token);
    // 添加方向变化和窗口大小变化监听
    window.addEventListener("resize", debounceLandscape);
    window.addEventListener("orientationchange", debounceLandscape);
  },
  {
    immediate: true,
  }
);

onMounted(() => {
  debounceLandscape();
});

// 初始化签字插件
function initSignature() {
  const cs: HTMLCanvasElement = document.querySelector("canvas") as HTMLCanvasElement;
  signature = new SmoothSignature(cs, {
    color: "#111",
    bgColor: "transparent",
  });
}

// 判断横竖屏
function forceLandscape() {
  isLandscape.value = window.innerWidth > window.innerHeight;
  // 延迟重新初始化签名板以适应新的屏幕尺寸
  setTimeout(() => {
    initSignature();
  }, 100);
}

/**
 * 清除
 */
function clear() {
  signature.clear();
}

/**
 * 完成
 */
function complete() {
  const pngBase64 = signature.getPNG();
  // console.log("pngBase64", pngBase64);
  if (!isLandscape.value) {
    // 竖屏：逆时针旋转90度
    rotateBase64Image(pngBase64, -90)
      .then((rotatedBase64) => {
        // console.log("旋转后的Base64:", rotatedBase64);
        // 使用旋转后的Base64数据
        const blob = base64ToBlob(rotatedBase64 as string, "image/png");
        uploadImage(blob);
      })
      .catch((error) => {
        console.error("旋转失败:", error);
      });
  } else {
    const blob = base64ToBlob(pngBase64, "image/png");
    uploadImage(blob);
  }
}

// 旋转Base64图片的函数
function rotateBase64Image(base64Data: string, degrees: number) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = function () {
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");

      // 设置canvas尺寸以适应旋转后的图片
      if (degrees % 180 === 0) {
        canvas.width = img.width;
        canvas.height = img.height;
      } else {
        canvas.width = img.height;
        canvas.height = img.width;
      }

      // 平移并旋转画布
      ctx?.translate(canvas.width / 2, canvas.height / 2);
      ctx?.rotate((degrees * Math.PI) / 180);

      // 绘制图片
      ctx?.drawImage(img, -img.width / 2, -img.height / 2);

      // 返回旋转后的Base64数据
      resolve(canvas.toDataURL());
    };
    img.onerror = reject;
    img.src = base64Data;
  });
}

// base64处理转换成文件
const base64ToBlob = (base64: string, type = "application/octet-stream") => {
  const cleanedBase64 = base64.replace(/^data:image\/png;base64,/, ""); // 清理前缀
  const byteCharacters = atob(cleanedBase64); // 解码Base64字符串
  const byteNumbers = new Uint8Array(byteCharacters.length);
  for (let i = 0; i < byteCharacters.length; i++) {
    byteNumbers[i] = byteCharacters.charCodeAt(i); // 将字符转换为字节
  }
  return new Blob([byteNumbers], { type: type }); // 创建Blob对象
};

// 上传签名
const uploadImage = (blob: Blob) => {
  const fileObj = new File([blob], `sign_image_${new Date().getTime()}.png`, { type: blob.type }); // 将 Blob 作为文件添加到 FormData
  // 文件上传
  FileAPI.uploadBusinessOne(fileObj)
    .then((res) => {
      bindBusiness(res.id as string);
    })
    .catch((error) => {
      console.error("上传失败:", error);
    });
};

// 业务绑定
function bindBusiness(signId: string) {
  switch (contractInfo.value?.type) {
    case "customerSign": // 合同签约
      ContractAPI.bindCustomerSign({
        contractId: contractInfo.value.id,
        customerSignId: signId,
      }).then(() => {
        ElMessage.success("签约成功");
        clear();
      });
      break;
    case "designSign": // 设计确认
      ContractDesignAPI.confirm({
        contractId: contractInfo.value.id,
        customerSignId: signId,
      }).then(() => {
        ElMessage.success("设计确认成功");
        clear();
      });
    default:
      break;
  }
}

onUnmounted(() => {
  window.removeEventListener("resize", debounceLandscape);
  window.removeEventListener("orientationchange", debounceLandscape);
});
</script>

<style lang="scss" scoped>
/* 正常横屏 */
.canvas-wrap {
  padding: 10px;
  display: flex;
  .canvas-box {
    width: 88%;
    height: calc(100vh - 20px);
    border: 1px solid #aaa;
    background-color: rgba(0, 0, 0, 0.1);
    #canvas {
      width: 100%;
      height: 100%;
    }
  }
  .canvas-btns {
    flex: 1;
    box-sizing: border-box;
    padding-left: 2%;
    .btn {
      width: 100%;
      height: 3em;
      margin-bottom: 12px;
    }
  }
}
/* 竖屏 */
.canvas-wrap-stand {
  height: 100%;
  padding: 10px;
  display: flex;
  flex-direction: column;
  .canvas-box {
    height: calc(100% - 5em);
    border: 1px solid #aaa;
    background-color: rgba(0, 0, 0, 0.1);
    #canvas {
      width: 100%;
      height: 100%;
    }
  }
  .canvas-btns {
    display: flex;
    flex: 1;
    box-sizing: border-box;
    justify-content: end;
    .canvas-btns-content {
      transform: rotate(90deg) translate(0, 2em);
      transform-origin: center;
    }
    .btn {
      width: 5em;
      height: 3em;

      margin-bottom: 12px;
    }
  }
}
</style>
